<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="/Public/js/three.min.js"></script>
    <script src="/Public/js/three_shaders.js"></script>
    <script src="/Public/js/OrbitControls.js"></script>
    <script src="/Public/js/jquery-3.7.1.min.js"></script>
    <script src="/Public/js/geotiff.js"></script>
    <script src="../deepSeekTest.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background: #1a1a2e;
            font-family: Arial, sans-serif;
        }
    </style>
</head>

<body>

    <script type="module">
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x1a1a2e);

        // 创建相机
        const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 10000);
        camera.position.set(4, 3.5, 3);

        // 创建渲染器
        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // 添加光源
        const ambientLight = new THREE.AmbientLight(0x404040);
        scene.add(ambientLight);
        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
        directionalLight.position.set(1, 1, 1);
        scene.add(directionalLight);

        // 添加控制器
        const controls = new THREE.OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true;

        //-------------------------------------
        const file = '/Public/imgs/dem/terrain2.tif';
        const res = await fetch(file)
        const arrayBuffer = await res.arrayBuffer();
        const tiff = await GeoTIFF.fromArrayBuffer(arrayBuffer)
        const image = await tiff.getImage()
        const rasters = await image.readRasters()
        const width = image.getWidth()
        const height = image.getHeight()
        const elevationData = new Float32Array(rasters[0])
        const geometry = new THREE.PlaneGeometry(5, 5 * height / width, width - 1, height - 1)
        let maxElevation = -Infinity
        for (let i = 0; i < elevationData.length; i++) {
            if (elevationData[i] > maxElevation) {
                maxElevation = elevationData[i]
            }
        }
        let minElevation = Infinity
        for (let i = 0; i < elevationData.length; i++) {
            const num = elevationData[i]
            if (num !== 0 && num < minElevation) {
                minElevation = num
            }
        }
        const positions = geometry.attributes.position.array
        for (let i = 0; i < elevationData.length; i++) {
            if (maxElevation == minElevation) {
                positions[i * 3 + 2] = 0
            }
            else {
                positions[i * 3 + 2] = (elevationData[i] - minElevation) / (maxElevation - minElevation)
            }
        }
        geometry.attributes.position.needsUpdate = true
        geometry.computeVertexNormals()

        // 原始网格（绿色线框）
        const material = new THREE.MeshBasicMaterial({
            color: '#00ff00',
            wireframe: true,
            transparent: true,
            opacity: 0.8
        })
        const mesh = new THREE.Mesh(geometry, material)
        mesh.rotateX(- Math.PI / 2)
        scene.add(mesh)

        // 点击后显示的网格（着色器材质）
        const vs1 = `
            varying vec2 vUv;
            varying vec3 vWorldPosition;
            void main() {
                vUv = uv;
                vec4 worldPosition = modelMatrix * vec4(position, 1.0);
                vWorldPosition = worldPosition.xyz;
                gl_Position = projectionMatrix * viewMatrix * worldPosition;
            }
        `
        const fs1 = `
            uniform vec3 circleCenter;
            uniform float circleRadius;
            varying vec3 vWorldPosition;
            
            void main() {
                float dist = length(vWorldPosition.xz - circleCenter.xz);

                if (dist < circleRadius) {
                    // 可以根据距离渐变颜色
                    float intensity = 1.0 - (dist / circleRadius);
                    vec3 color = mix(vec3(1.0, 0.0, 0.0), vec3(1.0, 1.0, 0.0), intensity);
                    gl_FragColor = vec4(color, 1.0);
                } else {
                    // 在区域外完全透明
                    discard;
                }
            }
        `

        const rt_mesh_material_circle = new THREE.ShaderMaterial({
            vertexShader: vs1,
            fragmentShader: fs1,
            side: THREE.DoubleSide,
            uniforms: {
                circleCenter: { value: new THREE.Vector3(0, 0, 0) },
                circleRadius: { value: 0.5 }
            },
            transparent: true
        })
        const rt_mesh = new THREE.Mesh(geometry, rt_mesh_material_circle)
        rt_mesh.rotateX(- Math.PI / 2)
        rt_mesh.visible = false; // 初始隐藏
        scene.add(rt_mesh)

        // 状态变量
        let isRedMode = false;

        // 鼠标交互
        const mouse = new THREE.Vector2();
        const raycaster = new THREE.Raycaster();

        function onMouseMove(event) {
            mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
            mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
        }

        function onMouseClick() {
            raycaster.setFromCamera(mouse, camera);

            // 根据当前状态检测不同的网格
            const targetMesh = isRedMode ? rt_mesh : mesh;
            const intersects = raycaster.intersectObject(targetMesh);

            if (intersects.length > 0) {
                const point = intersects[0].point;

                // 更新着色器的圆心位置
                rt_mesh_material_circle.uniforms.circleCenter.value.copy(point);
                rt_mesh_material_circle.uniforms.circleCenter.needsUpdate = true;

                isRedMode = !isRedMode;

                // mesh.visible = !isRedMode;
                rt_mesh.visible = isRedMode;
            }
        }

        window.addEventListener('mousemove', onMouseMove);
        window.addEventListener('click', onMouseClick);

        //-------------------------------------

        function animate() {
            requestAnimationFrame(animate);
            controls.update();
            renderer.render(scene, camera);
        }

        // 启动动画
        animate();

        // 窗口大小调整
        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    </script>
</body>

</html>